home *** CD-ROM | disk | FTP | other *** search
- /*
- * Info for setting video mode 640x400 gleaned from Ralf Brown's invaluable
- * Interrupt List.
- *
- * Other port-setting stuff is by Ben Morris.
- *
- * This mode uses planar writes. If you don't know what these are,
- * it's really simple:
- *
- * Planar mode was devised to get around the losers who decided
- * that memory should be accessed in 64k segments. Most planar
- * video modes use 4 horizontal planes, thus dividing the actual
- * amount of video memory displayed by 4. Basically, all 256000
- * bytes of video memory (which is what's used in 640x400) is
- * accessible in 64000 bytes.
- *
- * The thing about planar mode is that you have
- * to tell the video card (CRTC) to turn on the desired planes when
- * you want to write. Since there are four planes, and you can
- * set any combination of the four (like 0-2-3, 1-3, 0-1-2-3),
- * the CRTC requires that you pass it a byte explaining which
- * bits to set.
- *
- * This is really GOOD for lots of repetitive stuff (like filling
- * polygons with one color, etc), because it allows you to write
- * up to four bytes at a time.
- *
- * The BAD thing about this comes when looking at bitmaps. Bitmaps
- * are usually quite random. Basically, you'll have to set the
- * appropriate plane EACH AND EVERY TIME you want to write a pixel.
- *
- * I included a really simple pixel routine so you can see exactly
- * what my really bad explanation skills are trying to say. :).
- *
- * <grin>.
- *
- * PS: This code works with the ATI card. If you have a different
- * card (like a TSENG 4000 chipset), re-#define VIDMODE (below) to
- * the right card.
- *
- */
- #include <dos.h>
- #include <conio.h>
- #include <stdio.h>
- #include <mem.h>
-
- #define ATI_VGA 0x61
- #define TECMAR_VGA_AD 0x1B
- #define TSENG_4000 0x2F
- #define LOGIX 0x5C
- #define ATI_PRISM 0x5C
- #define MAXXON 0x5C
- #define SEFCO_TVGA 0x5C
- #define IMTEC 0x5C
- #define ZYMOS_POACH 0x5C
- #define TRIDENT_8800 0x5C
- #define TRIDENT_8900 0x5C
- #define PARADISE_VGA 0x5E
- #define VEGA_VGA 0x5E
- #define AST_VGA_PLUS 0x5E
- #define COMPAQ_VGA 0x5E
- #define AT_T_VDC600 0x5E
- #define TATUNG_VGA 0x66
- #define STB_VGA_EM16 0x78
- #define CARDINAL 0x78
-
- #define VIDMODE ATI_VGA
- #define UNKNOWN -1
- #define unint unsigned int
-
- /* Only available with 512k of ram */
- #define page1() outport(0x3D4, 0x800C)
- #define page0() outport(0x3D4, 0x0C)
-
- /*---------------------------------------------------------------------------*/
-
- int autodetect( void )
- /* This function will attempt to autodetect the video card/chipset in use.
- * I only have a small amount of information about it.
- *
- * Returns UNKNOWN (-1), or one of the #defines from above.
- *
- * If you have any more information about autodetection, PLEASE e-mail me
- * at the above addresses.
- *
- */
- {
- char far *ptr;
-
- /* Check for ATI? */
- ptr = (char far *) 0xc0000031L;
- if( !memcmp( ptr, "761295520", 9 ) )
- {
- /* It's an ATI, but what kind? */
- ptr = (char far *) 0xc0000040L;
-
- /* The signature "31" at this address means it's a VGA Wonder or compat. */
- if( !memcmp( ptr, "31", 2 ) )
- return ATI_VGA;
-
- goto unknown;
- }
-
- /* Check for Paradise VGA? */
- ptr = (char far *) 0xc000007d;
- if( !memcmp( ptr, "VGA=", 4 ) )
- return PARADISE_VGA;
-
- unknown:
- return UNKNOWN;
- }
-
- /*---------------------------------------------------------------------------*/
-
- void pixel( int page, int x, int y, char color )
- /* NOTE: PAGES ARE NOT FUNCTIONAL! Can anyone tell me why?
- */
- {
- char far *scr = (char far *) (0xa0000000L + (0x40000L * page)) + y * 160 + x / 4;
- unint masks[] = { 0x0102, 0x0202, 0x0402, 0x0802 };
-
- /* By the way, the masks above are used for plane setting. EG:
- * masks[0] sets plane 0, and so on.
- */
- outport( 0x3C4, masks[x%4] );
- *scr = color;
- }
-
- /*---------------------------------------------------------------------------*/
-
- void main( void )
- {
- long i, i2;
- char far *scr = (char far *) 0xa0000000L;
- int vtype = autodetect();
-
- if( vtype != -1 )
- {
- printf( "Video adaptor: 0x%X\n", vtype );
- getch();
- }
-
- _AH = 0;
- _AL = vtype == -1 ? VIDMODE : vtype;
- asm int 10h;
-
- outport( 0x3C4, 0x0604 ); /* turn off chain 4 + odd/even */
- outport( 0x3CE, 0x0106 ); /* turn off chain */
- outport( 0x3C4, 0x0f02 ); /* enable all planes */
-
- /* This writes 4 pixels at a time. */
- for( i = 0; i < 160L*400L; i++ )
- *scr++ = 15;
-
- getch();
-
- /* To see how slow planar writes are! */
- for( i = 0; i < 400L; i++ )
- for( i2 = 0; i2 < 640L; i2++ )
- pixel( 1, i2, i, 9 );
-
- getch();
-
- _AH = 0;
- _AL = 3;
- asm int 10h;
- }
-